package com.jvup.common.widget.snackbar;

import android.content.Context;
import android.content.res.TypedArray;
import android.util.AttributeSet;
import android.view.View;
import android.view.accessibility.AccessibilityManager;
import android.widget.FrameLayout;

import androidx.annotation.RestrictTo;
import androidx.annotation.RestrictTo.Scope;
import androidx.core.view.ViewCompat;
import androidx.core.view.accessibility.AccessibilityManagerCompat;
import androidx.core.view.accessibility.AccessibilityManagerCompat.TouchExplorationStateChangeListener;

import com.jvup.common.R;

@RestrictTo({Scope.LIBRARY_GROUP})
public class SnackBarLayout extends FrameLayout {
    private final AccessibilityManager accessibilityManager;
    private final TouchExplorationStateChangeListener touchExplorationStateChangeListener;
    private OnLayoutChangeListener onLayoutChangeListener;
    private OnAttachStateChangeListener onAttachStateChangeListener;

    public SnackBarLayout(Context context) {
        this(context, null);
    }

    public SnackBarLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
        TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.SnackBarLayout);
        if (a.hasValue(R.styleable.SnackBarLayout_elevation)) {
            ViewCompat.setElevation(this, (float)a.getDimensionPixelSize(R.styleable.SnackBarLayout_elevation, 0));
        }

        a.recycle();
        this.accessibilityManager = (AccessibilityManager)context.getSystemService(Context.ACCESSIBILITY_SERVICE);
        this.touchExplorationStateChangeListener = this::setClickableOrFocusableBasedOnAccessibility;
        AccessibilityManagerCompat.addTouchExplorationStateChangeListener(this.accessibilityManager, this.touchExplorationStateChangeListener);
        this.setClickableOrFocusableBasedOnAccessibility(this.accessibilityManager.isTouchExplorationEnabled());
    }

    private void setClickableOrFocusableBasedOnAccessibility(boolean touchExplorationEnabled) {
        this.setClickable(!touchExplorationEnabled);
        this.setFocusable(touchExplorationEnabled);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        int childCount = this.getChildCount();
        int availableWidth = this.getMeasuredWidth() - this.getPaddingLeft() - this.getPaddingRight();

        for(int i = 0; i < childCount; ++i) {
            View child = this.getChildAt(i);
            if (child.getLayoutParams().width == -1) {
                int measureWidth = MeasureSpec.makeMeasureSpec(availableWidth, MeasureSpec.EXACTLY);
                int measureHeight = MeasureSpec.makeMeasureSpec(child.getMeasuredHeight(), MeasureSpec.EXACTLY);
                child.measure(measureWidth, measureHeight);
            }
        }

    }

    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        super.onLayout(changed, l, t, r, b);
        if (this.onLayoutChangeListener != null) {
            this.onLayoutChangeListener.onLayoutChange(this, l, t, r, b);
        }

    }

    @Override
    protected void onAttachedToWindow() {
        super.onAttachedToWindow();
        if (this.onAttachStateChangeListener != null) {
            this.onAttachStateChangeListener.onViewAttachedToWindow(this);
        }

        ViewCompat.requestApplyInsets(this);
    }

    @Override
    protected void onDetachedFromWindow() {
        super.onDetachedFromWindow();
        if (this.onAttachStateChangeListener != null) {
            this.onAttachStateChangeListener.onViewDetachedFromWindow(this);
        }

        AccessibilityManagerCompat.removeTouchExplorationStateChangeListener(this.accessibilityManager, this.touchExplorationStateChangeListener);
    }

    void setOnLayoutChangeListener(OnLayoutChangeListener onLayoutChangeListener) {
        this.onLayoutChangeListener = onLayoutChangeListener;
    }

    void setOnAttachStateChangeListener(OnAttachStateChangeListener listener) {
        this.onAttachStateChangeListener = listener;
    }


    @RestrictTo({Scope.LIBRARY_GROUP})
    protected interface OnAttachStateChangeListener {
        void onViewAttachedToWindow(View view);

        void onViewDetachedFromWindow(View view);
    }

    @RestrictTo({Scope.LIBRARY_GROUP})
    protected interface OnLayoutChangeListener {
        void onLayoutChange(View view, int l, int t, int r, int b);
    }

}